package rhc.taskSchedule.taskSchedule;

import java.util.Date;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import rhc.discribute.node.host.Host;
import rhc.taskSchedule.BasicComponent;
import rhc.taskSchedule.entity.Running;
import rhc.taskSchedule.entity.RunningStatus;
import rhc.taskSchedule.entity.RunningType;
import rhc.taskSchedule.exception.RunningException;

/**running 相关基础函数
 * @author rhc
 *
 */
abstract public class BasicRunning extends BasicComponent implements BasicInterface{

	/**
	 * 运行id，每一次运行都会有一个独一无二的id
	 */
	protected String runningId;
	
	protected Running running;
	
	/**
	 * 当前节点
	 */
	protected Host currentHost;
	
	/**初始化running
	 * @throws Exception
	 */
	protected void initRunning() throws Exception{
		Running running=superDao.getOneT(new Query(Criteria.where(Running.COLUMN_ID).is(runningId)), Running.class);
		if(null == running){
			throw new RunningException("运行 {} 不存在", runningId);
		}
		RunningType runningType=getRunningType();
		if(!running.getRunningType().equals(runningType.type)){
			throw new RunningException("{} 类型错误，应该为 {} 类型",runningId,runningType.desc);
		}
	}
	
	/**获取运行类型，是任务类型还是调度类型
	 * @return
	 */
	abstract protected RunningType getRunningType();
	
	/**
	 * 开始运行该running
	 */
	protected void beginRun() throws Exception{
		checkBeginRun();
		Query query=new Query(Criteria.where(Running.COLUMN_ID).is(runningId));
		Update update=new Update();
		update.set(Running.COLUMN_RUNNING_STATUS, RunningStatus.RUN.status);
		update.set(Running.COLUMN_START_DATE, new Date());
		update.set(Running.COLUMN_RUN_NODE, currentHost.toString());
		
		superDao.updateFirst(query, update, Running.class);
	}
	
	/**暂停运行
	 * @throws Exception
	 */
	protected void pauseRun() throws Exception{
		checkBeginRun();
		Query query=new Query(Criteria.where(Running.COLUMN_ID).is(runningId));
		Update update=new Update();
		update.set(Running.COLUMN_RUNNING_STATUS, RunningStatus.PAUSE.status);
		
		superDao.updateFirst(query, update, Running.class);
	}
	
	/**恢复运行
	 * @throws Exception
	 */
	protected void regainRun() throws Exception{
		checkRegainRun();
		Query query=new Query(Criteria.where(Running.COLUMN_ID).is(runningId));
		Update update=new Update();
		update.set(Running.COLUMN_RUNNING_STATUS, RunningStatus.RUN.status);
		
		superDao.updateFirst(query, update, Running.class);
	}
	
	/**停止运行
	 * @throws Exception
	 */
	protected void stopRun() throws Exception{
		checkStopRun();
		Query query=new Query(Criteria.where(Running.COLUMN_ID).is(runningId));
		Update update=new Update();
		update.set(Running.COLUMN_RUNNING_STATUS, RunningStatus.STOP.status);
		update.set(Running.COLUMN_END_DATE, new Date());
		
		superDao.updateFirst(query, update, Running.class);
	}
	
	/**运行错误
	 * @param exception
	 * @throws Exception
	 */
	protected void errorRun(Exception exception) throws Exception{
		Query query=new Query(Criteria.where(Running.COLUMN_ID).is(runningId));
		Update update=new Update();
		update.set(Running.COLUMN_RUNNING_STATUS, RunningStatus.ERROR.status);
		update.set(Running.COLUMN_END_DATE, new Date());
		
		superDao.updateFirst(query, update, Running.class);
	}
	
	/**在开始运行任务前检查
	 * @throws Exception
	 */
	private void checkBeginRun() throws Exception{
		
	}
	
	/**在暂停运行前检查
	 * @throws Exception
	 */
	private void checkPauseRun() throws Exception{
		
	}
	
	/**在恢复运行前进行检查
	 * @throws Exception
	 */
	protected void checkRegainRun() throws Exception{
		
	}
	
	/**停止运行前检查
	 * @throws Exception
	 */
	protected void checkStopRun() throws Exception{
		
	}
	
	@Override
	public RunningStatus getRunStatus() throws Exception {
		int status=running.getRunningStatus();
		
		return RunningStatus.getRSByStatus(status);
	}
}
